#include "hilog/log.h"
#include "napi/native_api.h"
#include "native_db.h"
#include <bundle/native_interface_bundle.h>
#include <unistd.h>
#undef LOG_DOMAIN
#undef LOG_TAG
#define LOG_DOMAIN 0x0000
#define LOG_TAG "NAPI_init"
static OH_Rdb_Store *store;

// 沙箱数据库初始化
static napi_value InitDatabase(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value argv[1] = {nullptr};
    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);

    // 获取应用沙箱路径
    size_t sandboxPathSize;
    char sandboxPath[256];
    napi_get_value_string_utf8(env, argv[0], sandboxPath, sizeof(sandboxPath), &sandboxPathSize);
    OH_LOG_INFO(LOG_APP, "sandboxPath: %{public}s", sandboxPath);

    // 将bundleName传递给InitRdbStore用于初始化数据库
    OH_NativeBundle_ApplicationInfo nativeApplicationInfo = OH_NativeBundle_GetCurrentApplicationInfo();
    napi_value bundleName = nullptr;
    char bundleNameArr[1024] = {0};
    if (nativeApplicationInfo.bundleName != nullptr) {
        napi_status status =
            napi_create_string_utf8(env, nativeApplicationInfo.bundleName, NAPI_AUTO_LENGTH, &bundleName);
        if (status == napi_ok) {
            size_t nameSize;
            napi_get_value_string_utf8(env, bundleName, bundleNameArr, sizeof(bundleNameArr), &nameSize);
            store = InitRdbStore(sandboxPath, bundleNameArr);
            return nullptr;
        } else {
            OH_LOG_ERROR(LOG_APP, "Failed to create bundleName string");
            return nullptr;
        }
    } else {
        OH_LOG_ERROR(LOG_APP, "nativeApplicationInfo.bundleName is nullptr");
        return nullptr;
    }
}
// 向沙箱路径下的user.db写入数据
static napi_value WriteUserData(napi_env env, napi_callback_info info) {

    size_t argc = 2;
    napi_value argv[2] = {nullptr};
    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);

    size_t userNameSize;
    char userName[256];
    napi_get_value_string_utf8(env, argv[0], userName, sizeof(userName), &userNameSize);

    int userAge;
    napi_get_value_int32(env, argv[1], &userAge);
    napi_value status;
    napi_get_boolean(env, InsertUser(store, userName, userAge), &status);
    return status;
}
// 删除沙箱路径下的user.db数据
static napi_value DeleteUserData(napi_env env, napi_callback_info info) {
    // get parameters
    size_t argc = 1;
    napi_value args[1] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    int64_t productId = 0;
    napi_get_value_int64(env, args[0], &productId);
  
    napi_value status;
    napi_get_boolean(env, DeleteUser(store, productId), &status);
    return status;
}
// 读取沙箱路径下的user.db数据
static napi_value ReadUserData(napi_env env, napi_callback_info info) {
    napi_value resultArray;
    napi_create_array(env, &resultArray);

    std::vector<User> users = QueryUsers(store);
    for (size_t i = 0; i < users.size(); ++i) {
        napi_value userObject;
        napi_create_object(env, &userObject);

        // 添加id属性
        napi_value idValue;
        napi_create_int64(env, users[i].id, &idValue);
        napi_set_named_property(env, userObject, "id", idValue);

        // 添加name属性
        napi_value nameValue;
        napi_create_string_utf8(env, users[i].name, NAPI_AUTO_LENGTH, &nameValue);
        napi_set_named_property(env, userObject, "name", nameValue);

        // 添加age属性
        napi_value ageValue;
        napi_create_int64(env, users[i].age, &ageValue);
        napi_set_named_property(env, userObject, "age", ageValue);

        // 将用户对象添加到数组中
        napi_set_element(env, resultArray, i, userObject);
    }

    return resultArray;
}
// 将数据库信息写入文本文件当中
static napi_value WriteFileUsingPickerFd(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value argv[1] = {nullptr};
    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
    unsigned int fd = -1;
    napi_get_value_uint32(env, argv[0], &fd); // 获取文件描述符fd

    std::vector<User> users = QueryUsers(store);
    std::string dataToWrite;

    for (size_t i = 0; i < users.size(); ++i) {
        // 拼接数据
        dataToWrite += "ID: " + std::to_string(users[i].id) + "  " + "Name: " + users[i].name + "  " +
                       "Age: " + std::to_string(users[i].age) + "\n";
    }
    napi_value status;
    ftruncate(fd, 0); // 清除文件中的所有内容
    size_t buffSize = write(fd, dataToWrite.c_str(), dataToWrite.length());
    if (buffSize == -1) {
        OH_LOG_INFO(LOG_APP, "Write File Failed!!! ");
        napi_get_boolean(env, false, &status);
        return status;
    } else {
        OH_LOG_INFO(LOG_APP, "Write File Successfully!!!");
        napi_get_boolean(env, true, &status);
        return status;
    }
}
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports) {
    napi_property_descriptor desc[] = {
        {"initDatabase", nullptr, InitDatabase, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"writeUserData", nullptr, WriteUserData, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"deleteUserData", nullptr, DeleteUserData, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"readUserData", nullptr, ReadUserData, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"writeFileUsingPickerFd", nullptr, WriteFileUsingPickerFd, nullptr, nullptr, nullptr, napi_default, nullptr},
    };
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}
EXTERN_C_END

static napi_module demoModule = {
    .nm_version = 1,
    .nm_flags = 0,
    .nm_filename = nullptr,
    .nm_register_func = Init,
    .nm_modname = "entry",
    .nm_priv = ((void *)0),
    .reserved = {0},
};

extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
